// Import React dependencies.
import React, { useState, useCallback } from "react";
// Import the Slate editor factory.
import { Editor, createEditor, Transforms, Element } from "slate";

// Import the Slate components and React plugin.
import { Slate, Editable, withReact } from "slate-react";
// import { CodeElement } from "./pages/component/CodeElement";

const initialValue = [
  {
    type: "paragraph",
    children: [{ text: "A line of text in a paragraph." }],
  },
];

const App = () => {
  // Create a Slate editor object that won't change across renders.
  const [editor] = useState(() => withReact(createEditor()));

  // Define a rendering function based on the element passed to `props`. We use
  // `useCallback` here to memoize the function for subsequent renders.
  const renderElement = useCallback((props) => {
    switch (props.element.type) {
      case "code":
        return <CodeElement {...props} />;
      default:
        return <DefaultElement {...props} />;
    }
  }, []);

  // Define a leaf rendering function that is memoized with `useCallback`.
  const renderLeaf = useCallback((props) => {
    return <Leaf {...props} />;
  }, []);

  return (
    <Slate editor={editor} initialValue={initialValue}>
      <Editable
        renderElement={renderElement}
        // Pass in the `renderLeaf` function.
        renderLeaf={renderLeaf}
        onKeyDown={(event) => {
          if (!event.ctrlKey) {
            return;
          }
          // if (event.key === "`") {
          //   console.log("🚀 ~ App ~ event.key:", event.key);
          //   // Prevent the "`" from being inserted by default.
          //   event.preventDefault()
          //   // Determine whether any of the currently selected blocks are code blocks.
          //   const [match] = Editor.nodes(editor, {
          //     match: n => n.type === 'code',
          //   })
          //   // Toggle the block type depending on whether there's already a match.
          //   Transforms.setNodes(
          //     editor,
          //     { type: match ? 'paragraph' : 'code' },
          //     { match: n => Element.isElement(n) && Editor.isBlock(editor, n) }
          //   )
          // }

          switch (event.key) {
            // When "`" is pressed, keep our existing code block logic.
            case "`": {
              console.log(event.key);
              event.preventDefault();
              const [match] = Editor.nodes(editor, {
                match: (n) => n.type === "code",
              });
              Transforms.setNodes(
                editor,
                { type: match ? "paragraph" : "code" },
                {
                  match: (n) =>
                    Element.isElement(n) && Editor.isBlock(editor, n),
                }
              );
              break;
            }

            // When "B" is pressed, bold the text in the selection.
            case "b": {
              console.log(1111);
              event.preventDefault();
              Editor.addMark(editor, "bold", true);
              break;
            }
          }
        }}
      />
    </Slate>
  );
};

const CodeElement = (props) => {
  return (
    <pre {...props.attributes}>
      <code>{props.children}</code>
    </pre>
  );
};

const DefaultElement = (props) => {
  return <p {...props.attributes}>{props.children}</p>;
};

// Define a React component to render leaves with bold text.
const Leaf = (props) => {
  return (
    <span
      {...props.attributes}
      style={{ fontWeight: props.leaf.bold ? "bold" : "normal" }}
    >
      {props.children}
    </span>
  );
};

export default App;
